import { useMutation } from "react-relay";
import {useCallback, useContext, useState} from "react";
import {
  ConnectionHandler,
  RecordSourceSelectorProxy,
  RecordProxy
} from "relay-runtime";
import { PipingUnitInput } from "./__generated__/useNewPipingUnitMutation.graphql";
import {UserContext} from "../routing/UserContext";

const graphql = require("babel-plugin-relay/macro");

let tempID = 1;   //临时生成客户端自己的id，随后后端应答就被替换

//这个特别！返回{TodoEdge, User} 而不是直接返回TodoNode: Todo就可以了。!多出两个麻烦。
const mutation = graphql`
  mutation useNewPipingUnitMutation($pipe: ID!,$code: String!,$inp:PipingUnitInput) {
    newPipingUnit(pipe:$pipe,code:$code,inp: $inp) {
        id code 
      }
  }
`;

//TS不允许使用in作为回调函数参数名！所以graphQl接口参数名in不能用啊
export default function useNewPipingUnitMutation() {
  const [result, setResult] =useState(false);
  const [commit, isInFlight] = useMutation(mutation);
  return {
    call:useCallback(
      (pipe: string, code: string, inp:PipingUnitInput) => {
             //上面回调参数是 组件编辑器触发发过来的(text, userId)=>{};
        return commit({
          variables: {
            pipe, code, inp
          },
          updater: (store: RecordSourceSelectorProxy) => {
            const payload = store.getRootField("newPipingUnit");
            if (!payload) {
              return;
            }
            const retEqpId: any = payload.getValue("id");
            setResult(retEqpId);
            //只能获取到Node (=后端返回的payload模型)
            sharedUpdater(store, pipe, payload);
          },
          //optimisticUpdater: (store: RecordSourceSelectorProxy) => {      }
        });
      },
      [commit]
    ),
    isInFlight,
    result
  };
}

//相对原来直接操作store + Query{}接口直接查询的方式：目前用node()关联父对象然后集合字段[List]的ConnectionHandler模式，就不需要传递查询接口的参数。
//newEdge参数若是直接传进来一个Node对象也没大毛病，就是列表显示的数据不对。
function sharedUpdater(
    store: RecordSourceSelectorProxy,
    parentId: string,
    newNode: RecordProxy   //newEdge: RecordProxy
) {
  const fromObj = store.get(parentId);
  if (!fromObj) {
    return;
  }
  //找到连接点，两个模型【Set<>】  关联父对象然后 集合字段[List] 的@connection
  //关键！ TodoList_todos是关键标志。 在片段里面定义好了 @connection(key: "TodoList_todos")
  const connection = ConnectionHandler.getConnection(
      fromObj,
      "Pipeline_cell_list"
  );
  if (!connection) {
    return;
  }
  //返回 边的 用处在这里了。
  //特别返回的接口不用Node再包裹一层上Edges[Node]：AddTodoMutation
  //dataID临时不重要，  typeName必须的：xxxConnectionEdge
  const newEdge = store.create(
      "client:newEdge:" + tempID++,
      "PipingUnitConnectionEdge"
  );
  newEdge.setLinkedRecord(newNode, "node");
  ConnectionHandler.insertEdgeAfter(connection, newEdge);
}
